/*
 * Copyright 2014 OGIS-RI All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jp.co.ogis_ri.optaplanner.vehiclerouting.domain;

import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.core.AbstractPersistable;

/**
 * 位置情報
 *
 *
 */
public class Location extends AbstractPersistable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    /* 納品先ごとの配送依頼番号 */
    private String orderNo;

    /**
     * 位置の名称
     */
    private String name;

    /**
     * 位置の住所情
     */
    private String address;

    /**
     * 緯度
     */
    private double latitude;

    /**
     * 経度
     */
    private double longitude;

    /**
     * @return orderNo
     */
    public String getOrderNo() {
        return orderNo;
    }

    /**
     * @param orderNo セットする orderNo
     */
    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    /**
     * 位置の名称を取得する
     *
     * @return
     */
    public String getName() {
        return this.name;
    }

    /**
     * 位置の名称を設定する
     *
     * @param name
     */
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * @return address
     */
    public String getAddress() {
        return address;
    }

    /**
     * @param address セットする address
     */
    public void setAddress(String address) {
        this.address = address;
    }

    /**
     * 緯度を取得する
     *
     * @return
     */
    public double getLatitude() {
        return this.latitude;
    }

    /**
     * 緯度を設定する
     *
     * @param latitude
     */
    public void setLatitude(final double latitude) {
        this.latitude = latitude;
    }

    /**
     * 経度を取得する
     *
     * @return
     */
    public double getLongitude() {
        return this.longitude;
    }

    /**
     * 経度を設定する
     *
     * @param longitude
     */
    public void setLongitude(final double longitude) {
        this.longitude = longitude;
    }

    // ************************************************************************
    // Complex methods
    // ************************************************************************

    /**
     * 指定された位置との距離を求める
     *
     * @param location
     * @return
     */
    public int getDistance(final Location location) {
        // Implementation specified by TSPLIB
        // http://www2.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/
        // Euclidean distance (Pythagorean theorem) - not correct when the
        // surface is a sphere
//TODO 外部地図APIで実行

        double latitudeDifference = location.latitude - this.latitude;
        double longitudeDifference = location.longitude - this.longitude;
        double distance = Math.sqrt(latitudeDifference * latitudeDifference
                + longitudeDifference * longitudeDifference);
        return (int) (distance * 1000.0 + 0.5);

 // TODO       return new GoogleMaps(location.latitude, location.longitude, this.latitude, this.longitude).getGoogleMapsDirections().get(0);
    }

    /**
     * 指定された位置との移動距離を求める
     *
     * @param location
     * @return
     */
    public int getTravelTime(final Location location) {
        return this.getDistance(location);
// TODO        return new GoogleMaps(location.latitude, location.longitude, this.latitude, this.longitude).getGoogleMapsDirections().get(1);
    }

    @Override
    public String toString() {
        if (this.name == null) {
            return this.id.toString();
        }
        return this.id.toString() + "-" + this.name;
    }

}
